package org.jz.gae.redbook.spb.client.toolkit;

import java.util.ArrayList;
import java.util.List;


import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
import com.google.gwt.user.cellview.client.SimplePager;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTMLTable;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.SingleSelectionModel;

public class EntityViewGrid<T> extends Composite
{
	private final FlexTable contactsTable = new FlexTable();
	private final FlexTable rootTable = new FlexTable();
	private final Label loadingLabel = new Label("Loading");
	private final HorizontalPanel controlPanel = new HorizontalPanel();
	private final List<TableColumn> tableColumns = new ArrayList<TableColumn>();
	private int chosenRow = -1;
	private List<T> data;
	private final CellTable<T> cellTable = new CellTable<T>();
	private final List<TextColumn<T>> cellTableColumns = new ArrayList<TextColumn<T>>();
	private final SingleSelectionModel<T> selectionModel = new SingleSelectionModel<T>();
    SimplePager pager = new SimplePager();
    ListDataProvider<T> dataProvider = new ListDataProvider<T>();

	public interface ColumnValueDisplayer<C>
	{
		public String displayColumnValue(C _EntityView);
	}
	
	private class TableColumn
	{
		String title;
		String width;
		ColumnValueDisplayer<T> columnValueDisplayer;
	}
	
	public EntityViewGrid() 
	{
		SimplePanel contentTableDecorator = new SimplePanel();
		contentTableDecorator.addStyleName("gridContainer");
	    initWidget(contentTableDecorator);
	    contentTableDecorator.setWidth("100%");
		initializeInterface();
	    contentTableDecorator.add(rootTable);
	}
	
	private void initializeInterface() 
	{
		loadingLabel.setText("Загрузка....");
		/**/
	    contactsTable.setCellSpacing(0);
	    contactsTable.setCellPadding(0);
	    contactsTable.setWidth("100%");
	    contactsTable.addStyleName("grid");
	    //contactsTable.getColumnFormatter().setWidth(0, "150px");	
	    contactsTable.addClickHandler(new ClickHandler() {
	        public void onClick(ClickEvent event) {
	        	
	        	HTMLTable.Cell cell = contactsTable.getCellForEvent(event);
	        	
	        	if (cell != null)
	        	{
	        		int selectedRow = cell.getRowIndex();
	        		if (selectedRow == 0)
	        		{
	        			
	        		}
	        		else if (selectedRow > 0)
	        		{
	        			hideChosenRow();
	        			chosenRow = selectedRow - 1;
	        			highlightChosenRow();
	        		}
	        		else
	        		{
	        			
	        		}
	        	}
	          }
	        });
        /**/
	    rootTable.setWidth("100%");
	    rootTable.setWidget(0, 0, controlPanel);
	    /**/
	    cellTable.setWidth("100%");
	    cellTable.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
	    cellTable.setSelectionModel(selectionModel);
	    //cellTable.setVisibleRange(0, 4);
	    /**/
	    dataProvider.addDataDisplay(cellTable);
	    /**/
	    pager.setDisplay(cellTable);
	    pager.setPageSize(15);
	    /**/
	    switchToDataloading();
	    
	}

	private void switchToDataloading()
	{
	    rootTable.setWidget(1, 0, loadingLabel);
	}

	private void switchToDisplaying()
	{
		if (dataProvider.getList().size() <= pager.getPageSize())
		{
	        rootTable.setWidget(1, 0, null);
	        rootTable.setWidget(2, 0, cellTable);
		}
		else
		{
	        rootTable.setWidget(1, 0, pager);
	        rootTable.setWidget(2, 0, cellTable);
		}
	}
	
	public void addGridColumn(
			String _ColumnTitle,
			String _ColumnWidth,
			ColumnValueDisplayer<T> _ColumnValueDisplayer,
			TextColumn<T> _TextColumn)
	{
		TableColumn tableColumn = new TableColumn();
		tableColumn.title = _ColumnTitle;
		tableColumn.width = _ColumnWidth;
		tableColumn.columnValueDisplayer = _ColumnValueDisplayer;
		tableColumns.add(tableColumn);
		/**/
		_TextColumn.setSortable(true);
		cellTableColumns.add(_TextColumn);
		cellTable.addColumn(_TextColumn, _ColumnTitle);
		cellTable.setColumnWidth(_TextColumn, _ColumnWidth);
	}

	public HasClickHandlers getTable()
	{
		return contactsTable;
	}

	public void addButton(Button addButton)
	{
		controlPanel.add(addButton);
		
	}

	public void setData(
			List<T> data)
	{
		hideChosenRow();
		switchToDataloading();
	    contactsTable.removeAllRows();

    	for (int c = 0; c < tableColumns.size(); c++)
    	{
    		TableColumn column = tableColumns.get(c);
    		contactsTable.setText(0, c, column.title);
    		if (column.width != null)
    		{
     		    contactsTable.getCellFormatter().setWidth(0, c, tableColumns.get(c).width);
    		}
    	}
		contactsTable.getRowFormatter().addStyleName(0, "gridHeader");			
	    
		this.data = data;
		
	    for (int r = 0; r < data.size(); r++) 
	    {
	    	T entityView = data.get(r);
	    	for (int c = 0; c < tableColumns.size(); c++)
	    	{
	    		TableColumn column = tableColumns.get(c);
	    		contactsTable.setText(r + 1, c, column.columnValueDisplayer.displayColumnValue(entityView));
	    		if (column.width != null)
	    		{
     		        contactsTable.getCellFormatter().setWidth(r + 1, c, tableColumns.get(c).width);
	    		}
	    	}
	    }
	    
	    if (data.size() == 0)
	    {
	    	chosenRow = -1;
	    }
	    else
	    {
	    	chosenRow = 0;
	    }
	    
	    highlightChosenRow();
	    
	    dataProvider.getList().clear();
	    dataProvider.getList().addAll(data);

	    //cellTable.setRowCount(data.size());
	    //cellTable.setRowData(data);
	    
	    switchToDisplaying();
	}
	
	private void hideChosenRow()
	{
		if (chosenRow > -1)
		{
			contactsTable.getRowFormatter().removeStyleName(chosenRow + 1, "gridChosenRow");			
		}
	}

	private void highlightChosenRow()
	{
		if (chosenRow > -1)
		{
			contactsTable.getRowFormatter().addStyleName(chosenRow + 1, "gridChosenRow");			
		}
	}

	public T getSelectedEntityView()
	{
		/*
		if (chosenRow == -1)
		{
			return null;
		}
		else
		{
			return data.get(chosenRow);
		}
		*/
		return selectionModel.getSelectedObject();
	}
	

}
